//
//  Dialog.swift
//  
//
//  Created by tank on 2021/12/3.
//

import Foundation
import UIKit
import WebKit
import SwiftMessages
import RxSwift
import UIKit

public class Dialog {
    public typealias DialogCompletion = (_ buttonId: String?) -> Void
    
    public static let shared = Dialog()
    
    private var swiftMessagesDic: [String: SwiftMessages] = [:]
    
    private var closeButtonIds: [String: String] = [:]
    
    private init() {
    }
    
    public func alert(dialogId: String? = nil,
                      title: String? = nil,
                      message: String,
                      confirmButtonText: String? = nil,
                      interactive: Bool? = nil,
                      completion: DialogCompletion? = nil) {
        dialog(dialogType: .alert,
               dialogId: dialogId,
               title: title,
               message: message,
               confirmButtonText: confirmButtonText,
               interactive: interactive,
               completion: completion)
    }
    
    public func confirm(dialogId: String? = nil,
                        title: String? = nil,
                        message: String,
                        confirmButtonText: String? = nil,
                        cancelButtonText: String? = nil,
                        interactive: Bool? = nil,
                        completion: DialogCompletion? = nil) {
        dialog(dialogType: .confirm,
               dialogId: dialogId,
               title: title,
               message: message,
               confirmButtonText: confirmButtonText,
               cancelButtonText: cancelButtonText,
               interactive: interactive,
               completion: completion)
    }
    
    public func open(dialogId: String? = nil, url: String?, configuration: WKWebViewConfiguration) -> WKWebViewEx? {
        let dialogId = dialogId ?? UUID().uuidString
        guard !hasDuplicates(dialogId: dialogId) else {
            return nil
        }
        
        let dialogView = DialogView(id: dialogId,
                                    configuration: configuration)
        dialogView.set(url: url)
        
        show(dialogView: dialogView, interactive: false, completion: nil)
        
        return dialogView.webView
    }
    
    private func dialog(dialogType: DialogView.DialogType,
                        dialogId: String? = nil,
                        title: String? = nil,
                        message: String,
                        confirmButtonText: String? = nil,
                        cancelButtonText: String? = nil,
                        interactive: Bool?,
                        completion: DialogCompletion? = nil) {
        let dialogId = dialogId ?? UUID().uuidString
        guard !hasDuplicates(dialogId: dialogId) else {
            completion?(nil)
            return
        }
        
        let dialogView = DialogView(id: dialogId)
        dialogView.set(dialogType: dialogType,
                       title: title,
                       message: message,
                       confirmButtonText: confirmButtonText,
                       cancelButtonText: cancelButtonText)
        
        show(dialogView: dialogView, interactive: interactive, completion: completion)
    }
    
    private func hasDuplicates(dialogId: String,
                               completion: DialogCompletion? = nil) -> Bool {
        return swiftMessagesDic[dialogId] == nil ? false : true
    }
    
    private func show(dialogView: DialogView,
                      interactive: Bool?,
                      completion: DialogCompletion? = nil) {
        var presentViewController = UIViewController.ex.topMost
        if presentViewController?.parent is UITabBarController {
            presentViewController = presentViewController?.presentedViewController
        }
        
        var config = SwiftMessages.defaultConfig
        config.presentationStyle = .center
        config.dimMode = .gray(interactive: interactive ?? false)
        config.duration = .forever
        config.presentationContext = presentViewController != nil && !(presentViewController is WindowViewController) ? .view(presentViewController!.view) : .window(windowLevel: .alert)
        
        config.preferredStatusBarStyle = UIViewController.ex.topMost?
            .preferredStatusBarStyle
        config.interactiveHide = false
        config.eventListeners.append { [weak self] event in
            guard let strongSelf = self else {
                return
            }
            
            switch event {
            case .willShow: break
                
            case .didShow: break
                
            case .willHide: break
                
            case .didHide:
                strongSelf.swiftMessagesDic.removeValue(forKey: dialogView.id)
                
                let buttonId = strongSelf.closeButtonIds[dialogView.id]
                strongSelf.closeButtonIds.removeValue(forKey: dialogView.id)
                
                completion?(buttonId)
            }
        }
        
        let swiftMessages = SwiftMessages()
        swiftMessagesDic[dialogView.id] = swiftMessages
        swiftMessages.show(config: config, view: dialogView)
    }
    
    public func closeDialog(dialogId: String, buttonId: String) {
        closeButtonIds[dialogId] = buttonId
        swiftMessagesDic[dialogId]?.hide(id: dialogId)
    }
}
